
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <io.h>
#include <memory>
#include <fstream>
#include <sstream>
//#define _CRT_SECURE_NO_WARNINGS
extern "C"

{
#include "sqlite3.h"
};

using namespace std;


//shared_ptr<ofstream> ptr_out;

static ofstream* ptr_out=nullptr;


int tableInfo(void* para, int n_column, char** column_value, char** column_name);
int fieldWrite(void* para, int n_column, char** column_value, char** column_name);

void listFiles(const char* dir);


int fieldWrite(void* para, int n_column, char** column_value, char** column_name)
{
    ofstream outdata("D:/common/field.csv",ios::app);
    string str;
    for (int i = 0; i < n_column; i++)
    {
        if (i == 0)
        {
            str = str + column_value[i];
        }
        else
        {
            str = str + "," + column_name[i];
        }
        
    }
    outdata << str << endl;

    cout << "�ֶζ�ȡ���" << endl;


    return 0;
}

int tableInfo(void* para, int n_column, char** column_value, char** column_name)
{
    for (int i = 0; i < n_column; i++)
    {
        std::cout<<column_value[i]<<endl;
    }
    return 0;

}

void SplitString(const std::string& s, std::vector<std::string>& v, const std::string& c)
{
    std::string::size_type pos1, pos2;
    pos2 = s.find(c);
    pos1 = 0;
    while (std::string::npos != pos2)
    {
        v.push_back(s.substr(pos1, pos2 - pos1));

        pos1 = pos2 + c.size();
        pos2 = s.find(c, pos1);
    }
    if (pos1 != s.length())
        v.push_back(s.substr(pos1));
}





#include <stdio.h>
#include <stdlib.h>
//#include <sqlite3.h> 

static int callback(void* NotUsed, int argc, char** argv, char** azColName) {
    int i;
    for (i = 0; i < argc; i++) {
        printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
    }
    printf("\n");
    return 0;
}

void create_database() {
    sqlite3* db;
    char* zErrMsg = 0;
    int rc;
    //char* sql;

    /* Open database */
    rc = sqlite3_open("test.db", &db);

    if (rc) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return ;
    }
    else {
        fprintf(stdout, "Opened database successfully\n");
    }

    /* Create SQL statement */
    const char* sql = "CREATE TABLE ORDERBOOK("  \
        "ID INT PRIMARY KEY     NOT NULL," \
        "ticker           TEXT    NOT NULL," \
        "last            INT     NOT NULL," \
        "vol            INT     NOT NULL," \
        "bid            INT     NOT NULL," \
        "bsize            INT     NOT NULL," \
        "ask            INT     NOT NULL," \
        "asize            INT     NOT NULL," \
        "date        CHAR(50) );";

    /* Execute SQL statement */
    rc = sqlite3_exec(db, sql, callback, 0, &zErrMsg);

    if (rc != SQLITE_OK) {
        fprintf(stderr, "SQL error: %s\n", zErrMsg);
        sqlite3_free(zErrMsg);
    }
    else {
        fprintf(stdout, "Table created successfully\n");
    }
    sqlite3_close(db);

}


void insert_operation(string file) {
    sqlite3* db;
    char* zErrMsg = 0;
    int rc;

    /* Open database */
    rc = sqlite3_open("test.db", &db);

    if (rc) {
        fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
        return;
    }
    else {
        fprintf(stderr, "Opened database successfully\n");
    }


    /* Execute SQL statement */



    ifstream csv_file(file);
    string str;
    int identity = 2;

    getline(csv_file, str);
    while (getline(csv_file , str)) {

        vector<string> vec;
        SplitString(str, vec, ",");

        string values = "(" + to_string(identity++) + "," + "'" + vec[0] + "'" + ","
                                                              + vec[1] + ","
                                                              + vec[2] + ","
                                                              + vec[3] + ","
                                                              + vec[4] + ","
                                                              + vec[5] + ","
                                                              + vec[6] + ","
                                                        + "'" + vec[7] + "'" + ")";
                            ;

        string sql = "INSERT INTO  ORDERBOOK (ID,ticker, last, vol, bid, bsize, ask, asize, date) "  \
            "VALUES " + values + "; ";


        rc = sqlite3_exec(db, sql.c_str(), callback, 0, &zErrMsg);
        if (rc != SQLITE_OK) {
            fprintf(stderr, "SQL error: %s\n", zErrMsg);
            sqlite3_free(zErrMsg);
        }
        else {
            fprintf(stdout, "Records created successfully\n");
        }

    }
    sqlite3_close(db);
    return ;


}

//static is not must ,   but avoid becoming member function , should add it
static int sql_to_file(void* para, int n_column, char** column_value, char** column_name)

{

    //para������ sqlite3_exec �ﴫ��� void * ����

    //ͨ��para����������Դ���һЩ�����ָ�루������ָ�롢�ṹָ�룩��Ȼ����������ǿ��ת���ɶ�Ӧ�����ͣ���������void*���ͣ�����ǿ��ת����������Ͳſ��ã���Ȼ�������Щ����

    //n_column����һ����¼�ж��ٸ��ֶ� (��������¼�ж�����)

    // char ** column_value �Ǹ��ؼ�ֵ������������ݶ������������ʵ�����Ǹ�1ά���飨��Ҫ��Ϊ��2ά���飩��ÿһ��Ԫ�ض���һ�� char * ֵ����һ���ֶ����ݣ����ַ�������ʾ����/0��β��

    //char ** column_name �� column_value�Ƕ�Ӧ�ģ���ʾ����ֶε��ֶ�����



     //����Ҳ�ʹ�� para �������������Ĵ���.



    int i = 0;

    //printf("��¼���� %d ���ֶ� /n", n_column);
    string str;
    for (i = 0; i < n_column; i++)

    {
        if (i == 0){
            str = str + column_value[i];
        }
        else{
            str = str + "," + column_value[i];
        }

        //  printf("�ֶ���: %s  �ֶ�ֵ: %s /n", column_name[i], column_value[i]);

    }
  //  (*ptr_out) << str << endl;

    //printf("------------------ /n");

    return 0;

}


static int cmd_sql_show(void* para, int n_column, char** column_value, char** column_name){

    int i = 0;
    string str;
    for (i = 0; i < n_column; i++){
        if (i == 0){
            str = str + column_value[i];
        }
        else{
            str = str + "," + column_value[i];
        }
    }
    cout << str << endl;
    return 0;
}



// select name fromsqlite_master where type='table' order by name
// https://www.tutorialspoint.com/sqlite/sqlite_c_cpp.htm
void cmd_sql() {

    string fileStr;
    string  outPath = "orderbook_db.csv";             ///ȫ�ֱ���
    string dbPath = "test.db";
    ofstream out(outPath, ios::app);   ///����ļ����
  //  ptr_out = &out;


    string field = "ID,ticker, last, vol, bid, bsize, ask, asize, date";
    out << field << endl;
    sqlite3* db = nullptr;
    int result = -1;
    result = sqlite3_open(dbPath.c_str(), &db);
    if (result != 0)
    {
        std::cout << "��ʧ��" << std::endl;
    }

    //result = sqlite3_exec(db, "SELECT *  FROM  ORDERBOOK  ", cmd_sql_show, NULL, NULL);

    while (true) {
        string str;
        getline(cin, str);//cmd_sql_show
        result = sqlite3_exec(db, str.c_str(), callback, NULL, NULL);
    }


}

#include "db.h"
int main()
{
    //cmd_sql();
    MemoryDB db;
    db.load_config("table.config");
    db.load_insert_opt("insert_opt.config");
    db.create_database();
    db.create_table();
    db.insert_operation();
    db.cmd_sql();

    string sql = "CREATE TABLE ORDERBOOK("  \
        "ID INT PRIMARY KEY     NOT NULL," \
        "ticker           TEXT    NOT NULL," \
        "last            INT     NOT NULL," \
        "vol            INT     NOT NULL," \
        "bid            INT     NOT NULL," \
        "bsize            INT     NOT NULL," \
        "ask            INT     NOT NULL," \
        "asize            
        
             NOT NULL," \
        "date        CHAR(50) );";
    cout << sql;
    cmd_sql();
    //select_data();
    //create_database();//insert_operation("orderbook.csv");
    //cout << "Enter a directory: ";
    //cin.getline(dir, 200);

    return 0;
}

